package myzd.services.impl;

import com.google.common.base.Charsets;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import myzd.services.StateCacheService;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;

/**
 * Created by Mike He on 4/7/2017.
 */
@Component
public class InMemoryStateCacheService implements StateCacheService {

  @Autowired
  RedisTemplate<String, String> redisTemplate;

  private String hashState(Map<String, String> state) {
    Hasher hasher = Hashing.md5().newHasher();
    state.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(entry -> {
      hasher.putString(entry.getKey(), Charsets.UTF_8);
      hasher.putString(entry.getValue() == null ? "" : entry.getValue(), Charsets.UTF_8);
    });
    return Hex.encodeHexString(hasher.hash().asBytes());
  }

  @Override
  public String createCache(Map<String, String> state2cache) {
    if (state2cache == null) return null;
    String key = hashState(state2cache);
    redisTemplate.delete(key);
    redisTemplate.opsForHash().putAll(key, state2cache);
    redisTemplate.expireAt(key, DateUtils.addMinutes(new Date(), 10));
    return key;
  }

  @Override
  public Map<String, String> getState(String key) {
    HashOperations<String, String, String> hash = redisTemplate.opsForHash();
    return hash.entries(key);
  }

  @Override
  public void deleteState(String key) {
    redisTemplate.delete(key);
  }

}